#lang sicp
(define (rand)
  (random 4294967087))

(define (monte-carlo trials experiment)
  (define (iter passed remainder)
    (cond ((= 0 remainder)
           (+ (/ passed trials) 0.0 ))
          ((experiment)
           (iter (inc passed) (dec remainder)))
          (else
           (iter passed (dec remainder)))))
  (iter 0 trials))

(define (cesaro-test)
  (= (gcd (rand) (rand)) 1))

(define (estimate-pi trials)
 (sqrt (/ 6 (monte-carlo trials cesaro-test))))



(define (estimate-integral p x1 x2 y1 y2)
  (define (experiment)
    (p (rand-range x1 x2) (rand-range y1 y2)))
  (* (area-rectangle x1 x2 y1 y2)
     (monte-carlo 1555555 experiment)))

(define (rand-range low upper)
  (+ low (random (- upper low))))

(define (area-rectangle x1 x2 y1 y2)
  (* (- x2 x1) (- y2 y1)))

(define (make-test-area-circle r cx cy)
  (lambda (x y)
    (<= (+ (square (- x cx)) (square (- y cy)))
        (square r))))


(define (square x) (* x x))

(define in-unit-circle? (make-test-area-circle 1 5 5))





(define (rand-update x)
  (let ((a 7)
        (b 1200)
        (m 1212))
    (remainder (+ (* a x) b)
               m)))


(define (make-rand init-number)
  (lambda (m)
    (cond ((eq? m 'generate)
           (let ((x (rand-update init-number)))
             (set! init-number x)
             x))
          ((eq? m 'reset)
           (lambda (new-value)
             (set! init-number new-value)))
          (else
           (error "unkown operation ! -- MAKE-RAND" m)))))


(define new-rand (make-rand 10))
